/*-
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.last_pack.modelo.entidades;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author Arthur Tavares Bezerra
 */
public class Produto
{
    // Dasdos de identificação e definição de propriedades do produto 
    private Integer id;
    private String descricao;
    private BigDecimal preco;
    private Double peso;

    //Lacamentos do produto
    private List<LancamentoFisicoDeProduto> lancamentos;

    //Dados pré determinados (estáticos) para análise e gerenciamento do estoque.
    private Double giroTrabalhadoDeEntradasEmDias;
    private Double estoqueMinimoPreDeterminado;
    private Double estoqueMaximoPreDeterminado;
    private Double leadTimeFornecedor;

    //Usado para medir a precisao do estoque consumido no leadTime do fornecedor na sugestao da compra
    //Exemplo: Se a precisao for 100% não será acrescido nada à sugestão de compra
    private Double FatorPrecisaoDeTempoDeReposicao;

    //Dados online (dinâmicos) para análise e gerenciamento do estoque.
    public Double getGiroDeVendas( Date dataInicial, Date dataFinal )
    {
        Double giro = 0.0;

        Iterator<LancamentoFisicoDeProduto> iteratorLan = lancamentos.iterator(  );

        while ( iteratorLan.hasNext(  ) )
        {
            LancamentoFisicoDeProduto lancamento = iteratorLan.next(  );

            if ( lancamento.getMotivo(  ).equalsIgnoreCase( "Vendas" ) )
            {
                if ( ( 
                             ( lancamento.getData(  ).compareTo( dataInicial ) == 0 ) ||
                             lancamento.getData(  ).after( dataInicial )
                          ) &&
                         ( 
                                 ( lancamento.getData(  ).compareTo( dataFinal ) == 0 ) ||
                                 lancamento.getData(  ).before( dataFinal )
                              ) )
                {
                    giro += lancamento.getQuantidade(  );
                }
            }
        }

        return giro * -1;
    }

    public Double getSaldoDoEstoqueFisico( Date dataInicial, Date dataFinal )
    {
        Double saldo = 0.0;
        Iterator<LancamentoFisicoDeProduto> iteratorLan = lancamentos.iterator(  );

        while ( iteratorLan.hasNext(  ) )
        {
            LancamentoFisicoDeProduto lancamento = iteratorLan.next(  );

            if ( lancamento.getData(  ).after( dataInicial ) && lancamento.getData(  ).before( dataFinal ) )
            {
                saldo = saldo + lancamento.getQuantidade(  );
            }
        }

        return saldo;
    }

    public Double getSaldoDoEstoqueFisico(  )
    {
        Double saldo = 0.0;
        Iterator<LancamentoFisicoDeProduto> iteratorLan = lancamentos.iterator(  );

        while ( iteratorLan.hasNext(  ) )
        {
            LancamentoFisicoDeProduto lancamento = iteratorLan.next(  );
            saldo = saldo + lancamento.getQuantidade(  );
        }

        return saldo;
    }

    public String getDescricao(  )
    {
        return descricao;
    }

    public void setDescricao( String descricao )
    {
        this.descricao = descricao;
    }

    public Double getEstoqueMaximoPreDeterminado(  )
    {
        return estoqueMaximoPreDeterminado;
    }

    public void setEstoqueMaximoPreDeterminado( Double estoqueMaximoPreDeterminado )
    {
        this.estoqueMaximoPreDeterminado = estoqueMaximoPreDeterminado;
    }

    public Double getEstoqueMinimoPreDeterminadoEmDias(  )
    {
        return estoqueMinimoPreDeterminado;
    }

    public void setEstoqueMinimoPreDeterminadoEmDias( Double estoqueMinimoPreDeterminadoEmDias )
    {
        this.estoqueMinimoPreDeterminado = estoqueMinimoPreDeterminadoEmDias;
    }

    public Double getGiroTrabalhadoDeEntradasEmDias(  )
    {
        return giroTrabalhadoDeEntradasEmDias;
    }

    public void setGiroTrabalhadoDeEntradasEmDias( Double giroTrabalhadoDeEntradasEmDias )
    {
        this.giroTrabalhadoDeEntradasEmDias = giroTrabalhadoDeEntradasEmDias;
    }

    public Integer getId(  )
    {
        return id;
    }

    public void setId( Integer id )
    {
        this.id = id;
    }

    public List<LancamentoFisicoDeProduto> getLancamentos(  )
    {
        return lancamentos;
    }

    public void setLancamentos( List<LancamentoFisicoDeProduto> lancamentos )
    {
        this.lancamentos = lancamentos;
    }

    public Double getLeadTimeFornecedor(  )
    {
        return leadTimeFornecedor;
    }

    public void setLeadTimeFornecedor( Double leadTimeFornecedor )
    {
        this.leadTimeFornecedor = leadTimeFornecedor;
    }

    public Double getPeso(  )
    {
        return peso;
    }

    public void setPeso( Double peso )
    {
        this.peso = peso;
    }

    public BigDecimal getPreco(  )
    {
        return preco;
    }

    public void setPreco( BigDecimal preco )
    {
        this.preco = preco;
    }

    public Produto( Integer id, String descricao, BigDecimal preco, Double peso, Double giroPreDeterminadoEmDias,
                    Double estoqueMinimoPreDeterminadoEmDias, Double estoqueMaximoPreDeterminadoEmDias,
                    Double leadTimeFornecedor )
    {
        this.id = id;
        this.descricao = descricao;
        this.preco = preco;
        this.peso = peso;
        this.giroTrabalhadoDeEntradasEmDias = giroPreDeterminadoEmDias;
        this.estoqueMinimoPreDeterminado = estoqueMinimoPreDeterminadoEmDias;
        this.estoqueMaximoPreDeterminado = estoqueMaximoPreDeterminadoEmDias;
        this.leadTimeFornecedor = leadTimeFornecedor;
    }

    public Produto( Integer id, String descricao, BigDecimal preco, Double peso )
    {
        this.id = id;
        this.descricao = descricao;
        this.preco = preco;
        this.peso = peso;
    }

    @Override
    public String toString(  )
    {
        return "Produto{" + "id=" + id + ", descricao=" + descricao + ", preco=" + preco.abs(  ).setScale( 3, 1 ) +
               ", lancamentos=" + lancamentos.size(  ) + '}';
    }

    public String toStringFull(  )
    {
        return "Produto{" + "id=" + id + ", descricao=" + descricao + ", preco=" + preco.abs(  ).setScale( 3, 1 ) +
               ", lancamentos=" + lancamentos.size(  ) + ", leadTime=" + leadTimeFornecedor +
               ", giroTrabalhadoDeEntradasEmDias=" + giroTrabalhadoDeEntradasEmDias + '}';
    }

    public Double getFatorPrecisaoDeTempoDeReposicao(  )
    {
        return FatorPrecisaoDeTempoDeReposicao;
    }

    public void setFatorPrecisaoDeTempoDeReposicao( Double FatorPrecisaoDeTempoDeReposicao )
    {
        this.FatorPrecisaoDeTempoDeReposicao = FatorPrecisaoDeTempoDeReposicao;
    }

    public void setEstoqueMinimoPreDeterminado( Double estoqueMinimoPreDeterminado )
    {
        this.estoqueMinimoPreDeterminado = estoqueMinimoPreDeterminado;
    }

    public Double getEstoqueMinimoPreDeterminado(  )
    {
        return estoqueMinimoPreDeterminado;
    }
}
